<template>
  <div class="table-box">
    <el-button type="primary" @click="addRow">添加一条</el-button>
    <el-button type="primary" @click="submit(ruleFormRef)">提交</el-button>
    <el-switch
      v-model="entryMode"
      class="mb-2"
      active-text="单机获取复制焦点、双击唤醒输入框"
      inactive-text="点击唤醒输入框"
      @change="switchChange"
    />
    <el-form ref="ruleFormRef" :model="ruleForm" class="demo-ruleForm">
      <el-table
        border
        :data="ruleForm.tableData"
        :columns="columns"
        size="normal"
        @row-dblclick="onDoubleClickRow"
        @row-click="onClickRow"
        @cell-click="cellClick"
        @header-click="headerClick"
        :highlight-current-row="true"
      >
        <el-table-column v-for="(item, index) in columns" :key="index" :prop="item.key" :label="item.label" :data-index="index">
          <template #header="{ column, $index }">
            <span class="column-header"><i v-if="item.isCheck">*</i>{{ item.label }}</span>
          </template>

          <template #default="{row, $index}">
            <!-- 需要校验 -->
            <template v-if="$index >= 0 && item.key !== '' && item.isCheck">
              <el-tooltip placement="bottom" :content="row.isError[item.key].msg" effect="light" v-if="row.isError[item.key].msg !== ''">
                <div
                  v-if="!row.isEdit && item.type !== 'NONE'"
                  class="table-text"
                  :class="!row.isError[item.key].status ? 'error' : $index === currentRowIndex && index === currentColumnIndex ? 'active' : ''"
                >
                  <span class="text">{{ row[item.key] || '--' }}</span>
                  <el-icon class="edit"><EditPen /></el-icon>
                  <el-icon class="copy"><CopyDocument /></el-icon>
                </div>
                <div
                  class="table-text"
                  :class="!row.isError[item.key].status ? 'error' : $index === currentRowIndex && index === currentColumnIndex ? 'active' : ''"
                  v-if="row.isEdit && item.type !== 'NONE'"
                >
                  <base-form :columnData="item" :itemData="row"></base-form>
                </div>
              </el-tooltip>
              <template v-if="row.isError[item.key].msg === ''">
                <div
                  v-if="!row.isEdit && item.type !== 'NONE'"
                  class="table-text"
                  :class="!row.isError[item.key].status ? 'error' : $index === currentRowIndex && index === currentColumnIndex ? 'active' : ''"
                >
                  <span class="text">{{ row[item.key] || '--' }}</span>
                  <el-icon class="edit"><EditPen /></el-icon>
                  <el-icon class="copy"><CopyDocument /></el-icon>
                </div>
                <div class="table-text" v-if="row.isEdit && item.type !== 'NONE'">
                  <base-form :columnData="item" :itemData="row"></base-form>
                </div>
              </template>
            </template>
            <!-- 不需要校验 -->
            <template v-if="$index >= 0 && item.key !== '' && !item.isCheck">
              <div
                v-if="!row.isEdit && item.type !== 'NONE'"
                class="table-text"
                :class="$index === currentRowIndex && index === currentColumnIndex ? 'active' : ''"
              >
                <span class="text">{{ row[item.key] || '--' }}</span>
                <el-icon class="edit">
                  <EditPen />
                </el-icon>
                <el-icon class="copy">
                  <CopyDocument />
                </el-icon>
              </div>
              <div class="table-text" v-if="row.isEdit && item.type !== 'NONE'">
                <base-form :columnData="item" :itemData="row"></base-form>
              </div>
            </template>
            <!-- 按钮 -->
            <template v-if="item.type === 'NONE'">
              <el-button type="info" link @click.stop="saveRow(row, item)">
                确定
              </el-button>
              <el-button type="info" link @click.stop="delRow(row, item)">
                删除
              </el-button>
            </template>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
  </div>
</template>

<script setup>
import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
import baseForm from './baseForm.vue'
const entryMode = ref(false)

// 表单
const ruleFormRef = ref(0)
const ruleForm = ref({
  tableData: []
})
// const validateNode = (rule, value, callback) => {
//   let start = rule.field.lastIndexOf('.')
//   let key = rule.field.slice(start + 1, rule.field.length)
//   let index = Number(rule.field.replace(/[^\d]/g, ' '))
//   if (value === '') {
//     ruleForm.value.tableData[index].isError[key].status = false
//     ruleForm.value.tableData[index].isError[key].msg = '不能为空，请输入'
//     callback(new Error('不能为空，请输入'))
//   } else if (value.length >= 10) {
//     ruleForm.value.tableData[index].isError[key].status = false
//     ruleForm.value.tableData[index].isError[key].msg = '字数过多，最大输入10位'
//     callback(new Error('字数过多，最大输入10位'))
//   } else {
//     ruleForm.value.tableData[index].isError[key].status = true
//     ruleForm.value.tableData[index].isError[key].msg = ''
//     callback()
//   }
// }

// 提交表格
const submit = async (formEl) => {
  let keyName = []
  let valid = true
  Object.keys(ruleForm.value.tableData[0].isError).map((key) => {
    keyName.push(key)
  }) 
  ruleForm.value.tableData.forEach((item) => {
    keyName.forEach((k) => {
      if (item[k] === '') {
        item.isError[k].status = false
        item.isError[k].msg = '不能为空，请输入'
        valid = false
      }
    })
  })
  if (valid) {
  } else {
  } 
}
// 复制表格

const tableData = ref([
  {
    name: '李阿斯顿',
    age: 14,
    status: '是',
    isEdit: false,

    isError: {
      name: {
        status: true,
        msg: ''
      },
      age: {
        status: true,
        msg: ''
      },
      status: {
        status: true,
        msg: ''
      }
    }
  },
  {
    name: '李顿',
    age: 24,
    status: '否',
    isEdit: false,
    isError: {
      name: {
        status: true,
        msg: ''
      },
      age: {
        status: true,
        msg: ''
      },
      status: {
        status: true,
        msg: ''
      }
    }
  }
])
const emptyObj = ref({
  //全部列都可以粘贴
  // name: undefined,
  // age: undefined,
  // status: undefined
})
const defaultEmptyObj = ref({})
const currentRowIndex = ref(undefined)
const currentColumnIndex = ref(undefined)
const currentColumnKey = ref(undefined)
const rowsInfo = ref([])
const columns = ref([
  {
    key: 'name',
    label: '姓名',
    align: 'center',
    isCheck: true,
    type: 'TEXT'
  },
  {
    key: 'age',
    label: '年龄',
    align: 'center',
    isCheck: true,
    type: 'TEXT'
  },
  {
    key: 'status',
    label: '状态',
    align: 'center',
    isCheck: false,
    type: 'SELECT'
  },
  {
    key: '',
    label: '操作',
    align: 'center',
    type: 'NONE'
  }
])
const pasteInfo = (e) => {
  if (!entryMode.value) {
    return
  }
  try {
    let isEdit = false
    ruleForm.value.tableData.forEach((item) => {
      if (item.isEdit) {
        isEdit = item.isEdit
      }
    })
    if (isEdit) {
      return
    }
    var data = null
    var clipboardData = e.clipboardData // IE
    if (!clipboardData) {
      //chrome
      clipboardData = e.originalEvent.clipboardData
    }
    //复制过来的内容
    data = clipboardData.getData('Text')
    nextTick(() => {
      setTimeout(() => {
        //首先对源头进行解析
        var rowStrArray = data.split('\n') //拆成很多行
        rowsInfo.value = []
        emptyObj.value = {}
        defaultEmptyObj.value = {}
        for (var i = 0; i < rowStrArray.length - 1; i++) {
          var row = []
          var tdStrArray = rowStrArray[i].split('\t') //按列拆分
          for (var j = 0; j < tdStrArray.length; j++) {
            row.push(tdStrArray[j])
          }
          rowsInfo.value.push(row)
        }
        let columnslastIndex = rowsInfo.value[0].length - 1
        let columnsfirstIndex = columns.value.findIndex((item) => currentColumnKey.value == item.key)
        columns.value.map((item, index) => {
          let objkey = {
            [item.key]: undefined
          }
          if (index >= columnsfirstIndex && item.key !== '') {
            emptyObj.value = { ...emptyObj.value, ...objkey }
          }
          if (item.key !== '') {
            defaultEmptyObj.value = { ...defaultEmptyObj.value, ...objkey }
          }
        })
        let rowList = []
        for (var j = 0; j < rowsInfo.value.length; j++) {
          let temp = {
            isEdit: false,
            isError: {
              name: {
                status: true,
                msg: ''
              },
              age: {
                status: true,
                msg: ''
              },
              status: {
                status: true,
                msg: ''
              }
            }
          }
          let num = 0
          let numFlag = JSON.parse(JSON.stringify(currentColumnIndex.value))
          for (var key in emptyObj.value) {
            if (!rowsInfo.value[j][num]) {
              break
            }
            if (currentColumnIndex.value <= numFlag) {
              temp[key] = rowsInfo.value[j][num]
              num = num + 1
            }
            numFlag = numFlag + 1
          }
          if (tableData.value[currentRowIndex.value + j]) {
            let item = tableData.value[currentRowIndex.value + j]
            Object.keys(item).forEach((key) => {
              item[key] = temp[key] == undefined ? item[key] : temp[key]
            })
          } else {
            let keyName = {}
            for (var key in defaultEmptyObj.value) {
              if (!temp[key]) {
                keyName[key] = ''
              }
            }
            tableData.value.push({ ...keyName, ...temp })
          }
          rowList.push(temp)
        }
      }, 0)
    })
  } catch (err) {
  }
}
ruleForm.value.tableData = tableData.value
const prevRow = ref({})
// const onClickRow = (row, column, event) => {}

const clipboardlistFalg = ref(false) // 处理复制到输入框 还是复制循环到表格
// 切换唤醒输入框
const switchChange = (val) => {
  if (val) {
    let keyName = []
    Object.keys(ruleForm.value.tableData[0].isError).map((key) => {
      keyName.push(key)
    })
    ruleForm.value.tableData.forEach((item) => {
      item.isEdit = false
      keyName.forEach((k) => {
        item.isError[k].status = true
        item.isError[k].msg = ''
      })
    })
  }
}
// 当某一行被双击时会触发该事件
const onDoubleClickRow = (row, column, event) => {
  if (!entryMode.value) {
    if (prevRow.value.isEdit) {
      prevRow.value.isEdit = false
    }
    row.isEdit = true
    prevRow.value = row
    clipboardlistFalg.value = true
  }
}

// 当某一行被单击时会触发该事件
const onClickRow = (row, column, event) => {
  if (!entryMode.value) {
    if (prevRow.value.isEdit) {
      prevRow.value.isEdit = false
    }
    row.isEdit = true
    prevRow.value = row
    clipboardlistFalg.value = true
  }
}
// 当某个单元格被点击时会触发该事件
const cellClick = (row, column, cell, event) => {
  if (entryMode.value) {
    let rowIndex = tableData.value.findIndex((item) => item === row)
    currentColumnKey.value = column.property
    currentRowIndex.value = rowIndex
    currentColumnIndex.value = column.rawColumnKey
    clipboardlistFalg.value = false
  }
}
// 当某一列的表头被点击时会触发该事件
const headerClick = (column, event) => {
  if (entryMode.value) {
    currentColumnKey.value = column.property
    currentRowIndex.value = tableData.value.length
    currentColumnIndex.value = column.rawColumnKey
    clipboardlistFalg.value = false
  }
}
// 暂存
const saveRow = (row, item) => {
  row.isEdit = false
}
// 删除
const delRow = (row, item) => {
  tableData.value.splice(tableData.value.indexOf(row), 1)
}
// 新增
const addRow = () => {
  tableData.value.push({
    name: '',
    age: '',
    status: '',
    isEdit: true,
    isError: {
      name: {
        status: true,
        msg: ''
      },
      age: {
        status: true,
        msg: ''
      },
      status: {
        status: true,
        msg: ''
      }
    }
  })
  if (prevRow.value.isEdit) {
    prevRow.value.isEdit = false
  }
}
onMounted(() => {
  document.addEventListener('paste', (event) => {
    pasteInfo(event)
  })
})
onBeforeUnmount(() => {
  document.removeEventListener('paste', (event) => {
    pasteInfo(event)
  })
})
</script>

<style lang="scss">
#app {
  height: 100%;
}
</style>

<style lang="scss" scoped>
.table-box {
  height: 100%;
  margin-top: 0;
  :deep(.el-table) {
    --el-table-current-row-bg-color: #f4f8fe;
    --el-table-row-hover-bg-color: #f4f8fe;
    tr {
      td.el-table__cell {
        padding: 4px 0;
      }
      &:hover {
        .table-text {
          border: var(--el-table-border);
          background: #fff;
          cursor: text;
          .el-icon {
            opacity: 1;
          }
        }
      }
      .column-header {
        i {
          color: var(--el-color-danger);
          margin-right: 4px;
        }
      }
      .el-form-item {
        margin-bottom: 0;
      }
    }
  }
  .table-text {
    width: 100%;
    user-select: none;
    border: 1px solid transparent;
    border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
    transition: all 0.3s; // position: relative;
    display: flex;
    align-items: center;
    padding: 1px;
    .text {
      padding-left: 10px;
      flex: 1;
      line-height: 30px;
    }
    .el-icon {
      opacity: 0;
      padding-right: 10px;
      color: var(--el-color-info-light-3);
      &.copy {
        display: none;
        opacity: 0;
      }
    }
    &.error {
      // border-color: var(--el-color-danger);
      box-shadow: 0 0 0 1px var(--el-color-danger) inset;
    }
    &.active {
      // border-color: var(--el-color-danger);
      // box-shadow: 0 0 0 1px var(--el-color-primary) inset;
      .copy {
        display: block;
        opacity: 1;
      }
    }
  }
}
</style>
